package com.jumi.microservice.material.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jumi.microservice.common.exception.ExceptionSupply;
import com.jumi.microservice.common.redis.RedisCache;
import com.jumi.microservice.common.utils.StringProvider;
import com.jumi.microservice.common.wdt.WdtUtils;
import com.jumi.microservice.material.domain.JmGoods;
import com.jumi.microservice.material.domain.JmSupplier;
import com.jumi.microservice.material.dto.*;
import com.jumi.microservice.material.mapper.*;
import com.jumi.microservice.material.service.GoodsTaxService;
import com.jumi.microservice.material.service.JmGoodsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ssk
 * @create 2020/8/4 16:51
 **/
@Service
public class JmGoodsServiceImpl implements JmGoodsService {

    @Resource
    private JmGoodsMapper jmGoodsMapper;

    @Resource
    private JmMaterialMapper jmMaterialMapper;

    @Resource
    private JmSupplierMapper supplierMapper;

    @Resource
    private RedisCache redisCache;

    @Resource
    private JmCategoryMapper categoryMapper;

    @Resource
    private JmMaterialSmallUnitMapper unitMapper;

    @Autowired
    private GoodsTaxService goodsTaxService;


    @Override
    @Transactional
    public int save(JmGoodsRequest jmGoodsRequest) {
        //商品头标SP
        Map<String, Object> map = createSPCode();
        String spCode = map.get("sp_code").toString();
        List<JmMaterialRequest> materials = jmGoodsRequest.getMaterials();
        jmGoodsRequest.setGoodsCode(spCode);
        JmGoods jmGoods = this.cloneProperties(jmGoodsRequest);
        //保存商品信息
        int rows = jmGoodsMapper.save(jmGoods);
        if (materials == null || materials.size() == 0) {
            throw new ExceptionSupply(500, StringProvider.format("产品::{}中至少要有一条物料信息", jmGoods.getGoodsName())).newException();
        }
        for (int i = 0; i < materials.size(); i++) {
            JmMaterialRequest material = materials.get(i);
            //物料头标WL
            String mCode = createWLCode(spCode, (i + 1));
            material.setGoodsId(jmGoods.getGoodsId());
            material.setMaterialCode(mCode);
            if (material.getOtherCode() == null) {
                material.setOtherCode("");
            }
            material.setCreateBy(jmGoods.getCreateBy());
        }
        //保存物料信息
        jmMaterialMapper.saveBatch(materials);

        this.saveLinks(materials);

        // 推送到旺店通
//        try {
//            List<JmGoodsRequest> pushList = new ArrayList<>();
//            pushList.add(jmGoodsRequest);
//            JSONObject pushJson = WdtUtils.goodsPush(pushList);
//            JSONObject json = WdtUtils.goodsQuery(spCode);
//            JSONObject wdtGoods = json.getJSONArray("goods_list").getJSONObject(0);
//            Long wdtGoodsId = wdtGoods.getLong("goods_id");
//            jmGoods.setWdtGoodsId(wdtGoodsId);
//            jmGoodsMapper.update(jmGoods);
//        } catch (Exception e) {
//            throw new ExceptionSupply(500, "推送旺店通失败!").newException();
//        }
        redisCache.setCacheObject("last_sp_id", map.get("sp_id"));
        return rows;
    }

    /**
     * 物料属性关联保存方法
     *
     * @param materials
     */
    private void saveLinks(List<JmMaterialRequest> materials) {
        List<Map<String, Object>> links = new ArrayList<>();
        for (JmMaterialRequest material : materials) {
            Long[] attrValueIds = material.getAttrValueIds();
            for (int i = 0; i < attrValueIds.length; i++) {
                Map<String, Object> link = new HashMap<>();
                link.put("materialId", material.getMaterialId());
                link.put("attrValId", attrValueIds[i]);
                links.add(link);
            }
        }
        //保存属性信息
        if (links.size() > 0) {
            jmMaterialMapper.deleteLinks(links);
            jmMaterialMapper.saveAttrValues(links);
        }

    }

    @Override
    @Transactional
    public int update(JmGoodsRequest jmGoodsRequest) {
        JmGoods jmGoods = this.cloneProperties(jmGoodsRequest);
        //更新商品信息
        int rows = jmGoodsMapper.update(jmGoods);
        List<JmMaterialRequest> materials = jmGoodsRequest.getMaterials();
        if (materials != null) {
            String maxCode = jmMaterialMapper.findMaxCodeByGoodsId(jmGoods.getGoodsId());
            StringBuffer sb = new StringBuffer("0");
            sb.append(maxCode.substring(maxCode.lastIndexOf(".")));
            BigDecimal maxNum = new BigDecimal(sb.toString());
            maxNum = maxNum.multiply(BigDecimal.valueOf(1000));
            int maxId = maxNum.intValue();
            List<JmMaterialRequest> updateList = new ArrayList<>();
            List<JmMaterialRequest> saveList = new ArrayList<>();
            for (int i = 0; i < materials.size(); i++) {
                JmMaterialRequest material = materials.get(i);
                Long materialId = material.getMaterialId();
                if (materialId == null) {
                    maxId++;
                    String mCode = createWLCode(jmGoods.getGoodsCode(), maxId);
                    material.setMaterialCode(mCode);
                    material.setGoodsId(jmGoods.getGoodsId());
                    material.setCreateBy(jmGoods.getUpdateBy());
                    saveList.add(material);
                } else {
                    material.setUpdateBy(jmGoods.getUpdateBy());
                    updateList.add(material);
                }
            }

            //保存物料信息
            if (saveList.size() > 0) {
                jmMaterialMapper.saveBatch(saveList);
                this.saveLinks(materials);
            }
            //更新物料信息
            if (updateList.size() > 0)
                jmMaterialMapper.updateBatch(updateList);
//            int a=10/0;
            // 推送到旺店通

//            try {
//                List<JmGoodsRequest> pushList = new ArrayList<>();
//                pushList.add(jmGoodsRequest);
//                WdtUtils.goodsPush(pushList);
//            } catch (Exception e) {
//                throw new ExceptionSupply(500, "推送旺店通失败!").newException();
//            }

        }

        return rows;
    }

    @Override
    public void deleteBatch(Long[] goodsIds) {
        jmGoodsMapper.deleteBatch(goodsIds);
    }

    @Override
    public JmGoodsResponse findById(Long goodsId) {

        try {
            JmGoodsResponse response = jmGoodsMapper.findById(goodsId);
            List<JmMaterialResponse> materials = response.getMaterials();
            if (materials != null && materials.size() > 0) {
                List<Long> materialIds = new ArrayList<>();
                for (JmMaterialResponse m : materials) {
                    materialIds.add(m.getMaterialId());
                }
                List<JmAttrResponse> attrs = jmMaterialMapper.findAttrs(materialIds);
                for (JmAttrResponse attr : attrs) {
                    Map<String, Object> param = new HashMap<>();
                    param.put("attrId", attr.getAttrId());
                    param.put("materialIds", materialIds);
                    List<JmAttrValResponse> vals = jmMaterialMapper.findAttrVals(param);
                    attr.setAttrVals(vals);
                }
                response.setAttrs(attrs);
            }
            return response;
        } catch (Exception e) {
            throw new ExceptionSupply(500, "数据库查询错误").newException();
        }
    }

    @Override
    @Transactional
    public List<JmGoodsResponse> findAll(JmGoodsRequest jmGoodsRequest) {
        if (StringUtils.isNotBlank(jmGoodsRequest.getSupplierCompanyName())) {
            JmSupplier supplier = new JmSupplier();
            supplier.setSupplierCompanyName(jmGoodsRequest.getSupplierCompanyName());
            List<JmSupplier> suppliers = supplierMapper.findAll(supplier);
            List<Long> supplierIds = new ArrayList<>();
            for (JmSupplier sup : suppliers) {
                supplierIds.add(sup.getSupplierId());
            }
            if (supplierIds.size() > 0)
                jmGoodsRequest.setSupplierIds(supplierIds);
            else
                return new ArrayList<>();
        }
        return jmGoodsMapper.findAll(jmGoodsRequest);
    }

    @Override
    public List<JmGoodsResponse> findAllDetail(JmGoodsRequest jmGoodsRequest) {
        return jmGoodsMapper.findAllDetails(jmGoodsRequest);
    }

    @Override
    public List<Map<Object, Object>> getGoodsMaterialCountByGoodsIds(List<Long> goodsIds) {

        return jmGoodsMapper.getGoodsMaterialCountByGoodsIds(goodsIds.stream().distinct().collect(Collectors.toList()));
    }

    @Override
    public List<JmMaterialResponse> findMaterialsDetail(Long goodsId, Long warehouseId) {
        return jmGoodsMapper.findMaterialsDetail(goodsId, warehouseId);
    }

    /**
     * 批量导入接口
     *
     * @param list
     * @param createBy
     * @return
     */
    @Override
    @Transactional
    public String importData(List<JmGoodsResponse> list, String createBy) {

        if (list == null || list.size() == 0)
            throw new ExceptionSupply(500, "上传数据为空").newException();

        List<JmGoodsRequest> goodsRequests = new ArrayList<>();
        for (JmGoodsResponse goods : list) {
            String goodsName = goods.getGoodsName();
            int count = jmGoodsMapper.findByGoodsName(goodsName);
            if (count > 0)
                throw new ExceptionSupply(500, "系统中已存在产品::" + goodsName).newException();
            String cateName = goods.getCateName();
            Integer goodsType = goods.getGoodsType();
            String unitName = goods.getUnitName();
            Integer expire = goods.getExpire();
            String supplierCompany = goods.getSupplierCompanyName();
            String barCode = goods.getBarCode();
            String otherCode = goods.getOtherCode();
            String attrName = goods.getAttrName();
            String specName = goods.getSpecName();
            BigDecimal weight = goods.getWeight();
            String taxCode = goods.getTaxCode();
            if (StringUtils.isBlank(goodsName) || StringUtils.isBlank(cateName)
                    || StringUtils.isBlank(unitName) || StringUtils.isBlank(supplierCompany)
                    || goodsType == null || expire == null || taxCode==null) {
                throw new ExceptionSupply(500, "必填项有空数据!").newException();
            }

            //根据taxCode查询taxId
            Integer taxId;
            taxId = goodsTaxService.findTaxIdByTaxCode(taxCode);
            if(taxId==null)
                throw new ExceptionSupply(500, goods.getGoodsName()+"的税务编码有误!").newException();

            JmGoodsRequest jmGoodsRequest = new JmGoodsRequest();
            jmGoodsRequest.setGoodsName(goodsName);
            Long cateId = categoryMapper.findByName(cateName);
            if (cateId == null)
                throw new ExceptionSupply(500, "请到系统中添加分类::" + cateName).newException();
            jmGoodsRequest.setCateId(cateId);
            jmGoodsRequest.setGoodsType(goodsType);
            Long unitId = unitMapper.findByUnitName(unitName);
            if (unitId == null)
                throw new ExceptionSupply(500, "系统中最小单位::" + unitName+"不存在或已被禁用").newException();
            jmGoodsRequest.setUnitId(unitId);
            jmGoodsRequest.setExpire(expire);
            Long supplierId = supplierMapper.findByCompanyName(supplierCompany);
            if (supplierId == null)
                throw new ExceptionSupply(500, "请到系统中添加供应商厂家名称::" + supplierCompany).newException();
            jmGoodsRequest.setSupplierId(supplierId);
            jmGoodsRequest.setCreateBy(createBy);
            jmGoodsRequest.setTaxId(taxId);

            // 封装物料
            JmMaterialRequest material = new JmMaterialRequest();
            material.setBarCode(barCode);
            material.setOtherCode(otherCode);

            if (StringUtils.isBlank(attrName)) {
                Long[] attrValueIds = {};
                material.setAttrValueIds(attrValueIds);
                material.setSpecName("无属性");
            } else {
                String[] attrNames = attrName.split(",");
                String[] specNames = specName.split(",");
                if (attrNames.length != specNames.length)
                    throw new ExceptionSupply(500, "属性与属性值不匹配!").newException();
                List<Long> valIdList=new ArrayList<>();
                for (int i = 0; i < attrNames.length; i++) {
                    String attr = attrNames[i], spec = specNames[i];
                    Long attrValueId = jmGoodsMapper.findAttrValueIdByName(attr, spec);
                    if (attrValueId == null)
                        throw new ExceptionSupply(500, StringProvider.format("不存在{}为{}的数据,请到系统中添加后再试", attr, spec)).newException();
                    valIdList.add(attrValueId);
                }
                Long[] attrValueIds = new Long[valIdList.size()];
                material.setAttrValueIds(valIdList.toArray(attrValueIds));
                material.setSpecName(specName);
            }
            material.setWeight(weight);
            boolean isExist = false;
            for (JmGoodsRequest obj : goodsRequests) {
                if (obj.getGoodsName().equals(goodsName)) {
                    List<JmMaterialRequest> materials = obj.getMaterials();
                    materials.add(material);
                    obj.setMaterials(materials);
                    isExist = true;
                    break;
                }
            }
            if (isExist)
                continue;
            List<JmMaterialRequest> materials = new ArrayList<>();
            materials.add(material);
            jmGoodsRequest.setMaterials(materials);
            goodsRequests.add(jmGoodsRequest);
        }
        // 遍历添加商品
        for (JmGoodsRequest goodsRequest : goodsRequests) {
            this.save(goodsRequest);
        }
        return "success";
    }

    private JmGoods cloneProperties(JmGoodsRequest jmGoodsRequest) {
        JmGoods jmGoods = new JmGoods();
        jmGoodsRequest.clone(jmGoods);
        return jmGoods;
    }

    /**
     * 因文案商品改为产品
     * 故头标 sp->cp
     *
     * @return
     */
    private Map<String, Object> createSPCode() {
        Map<String, Object> map = new HashMap();
        Long maxId =  Long.valueOf(redisCache.getCacheObject("last_sp_id").toString());
        if (maxId != null) {
            StringBuffer sb = new StringBuffer("CP");
            Long nextId = maxId + 1;
            if (nextId > 99999) {
                throw new ExceptionSupply(500, "商品编码超出最大限制<100000)").newException();
            }
            BigDecimal codeNum = BigDecimal.valueOf(nextId).divide(BigDecimal.valueOf(100000));
            String tempStr = codeNum.toString();
            String codeStr = tempStr.substring(tempStr.indexOf("."));
            sb.append(codeStr);
            int fillSize = 8 - sb.length();
            for (int i = 0; i < fillSize; i++) {
                sb.append("0");
            }
            map.put("sp_code", sb.toString());
            map.put("sp_id", nextId);
            return map;
        } else {
            maxId = jmGoodsMapper.findMaxGoodsId();
            maxId = maxId == null ? 0 : maxId;
            redisCache.setCacheObject("last_sp_id", maxId);
            return createSPCode();
        }

    }

    private String createWLCode(String spCode, int sort) {
        if (sort > 999) {
            throw new ExceptionSupply(500, "物料编码超出最大限制(<1000)").newException();
        }
        String wlHead = spCode.replace("CP", "WL");
        StringBuffer sb = new StringBuffer(wlHead);
        BigDecimal codeNum = BigDecimal.valueOf(sort).divide(BigDecimal.valueOf(1000));
        String tempStr = codeNum.toString();
        String codeStr = tempStr.substring(tempStr.indexOf("."));
        sb.append(codeStr);
        return sb.toString();
    }
}
